#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <errno.h>

enum IOCTL_ENUM{
    IOCTL_START = 0,
    IOCTL_SET_PID,
    IOCTL_END,   
};

char *dev_name = "/dev/template";

// 信号处理函数
static void signal_handler(int signum, siginfo_t *info, void *context)
{
	// 打印接收到的信号值
    printf("[app]signal_handler: signum = %d \n", signum);
    printf("[app]signo = %d, code = %d, errno = %d \n",
	         info->si_signo,
	         info->si_code, 
	         info->si_errno);
}

int main(int argc, char *argv[])
{
	int fd;
	int pid = getpid();
	int read_pid = 0;
	int ret;
	char to_kernel_str[] = "hello kernel";

	// 打开设备节点 调用open函数
	if((fd = open(dev_name, O_RDWR | O_NDELAY)) < 0)
	{
		printf("[app] open dev failed! \n");
		return -1;
	}
	
	// 注册信号处理函数
	struct sigaction sa;
	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = &signal_handler;
	sa.sa_flags = SA_SIGINFO;

	sigaction(SIGIO, &sa, NULL);

	// 调用ioctl信号 cmd = IOCTL_SET_PID arg = pid 
	ret = ioctl(fd, IOCTL_SET_PID, &pid);
	if(ret != 0)
	{
		printf("[app] call ioctl failed. errno = %d \n", ret);
	}

	// 调用read信号 read_pid
	ret = read(fd, &read_pid, sizeof(read_pid));
    if(ret == 0) 
    {             
        printf("[app] read: %d\n", read_pid);
    }

	// 调用write信号 to_kernel_str = ubuf  sizeof(to_kernel_str) = cnt
	ret = write(fd, to_kernel_str, sizeof(to_kernel_str));
    if(ret == 0) 
    {             
        printf("[app] write success\n", ret);
    }

	// 休眠1秒，等待接收信号
	while (1)
	{
		sleep(1);
	}

	// 关闭设备 调用relase信号
	close(fd);
}

